#ifndef VRP_SHADOW_INCLUDED
#define VRP_SHADOW_INCLUDED
#include "ShadowInput.hlsl"
#include "../../Shaders/VLitInput.hlsl"
#include "ShadowBias.hlsl"
#include "ShadowTentFilter.hlsl"
///将坐标从世界坐标系转换到主灯光的裁剪空间
int GetCascadeIndex(float3 positionWS)
{
    for(int i = 0; i < ACTIVED_CASCADE_COUNT; i ++){
        float4 cullingSphere = _VCascadeCullingSpheres[i];
        float3 center = cullingSphere.xyz;
        float radiusSqr = cullingSphere.w * cullingSphere.w;
        float3 d = (positionWS - center);
        //计算世界坐标是否在包围球内。
        if(dot(d,d) <= radiusSqr){
            return i;
        }
    }
    return - 1;
}
///将世界坐标转换到ShadowMapTexture空间,返回值的xy为uv，z为深度
float3 WorldToShadowMapPos(float3 positionWS,int cascadeIndex){
    if(cascadeIndex >= 0){
        float4x4 worldToCascadeMatrix = _VWorldToMainLightCascadeShadowMapSpaceMatrices[cascadeIndex];
        float4 shadowMapPos = mul(worldToCascadeMatrix,float4(positionWS,1));
        shadowMapPos /= shadowMapPos.w;
        return shadowMapPos;
    }else{
        //表示超出ShadowMap. 不显示阴影。
        #if UNITY_REVERSED_Z
        return float3(0,0,1);
        #else
        return float3(0,0,0);
        #endif
    }
}
float3 WorldToShadowMapPos(float3 positionWS)
{
    int cascadeIndex = GetCascadeIndex(positionWS);
    return WorldToShadowMapPos(positionWS,cascadeIndex);
}
///采样阴影强度，返回区间[0,1]
float SampleShadowStrength(float3 uvd)
{
    #if V_SHADOW_PCF
    float atten = 0;
    atten = SampleShadowPCF(uvd);
    return 1-atten;
    #else
    float depth =_VMainShadowMap.Sample(sampler_VMainShadowMap_point_clamp,uvd.xy);
    #if UNITY_REVERSED_Z
    // depthToLight < depth 表示在阴影之中
    return clamp(step(uvd.z + _ShadowParams.x,depth), 0,_ShadowParams.z);
    #else
    // depthToLight > depth表示在阴影之中
    return clamp(step(depth,uvd.z - _ShadowParams.x), 0,_ShadowParams.z);
    #endif
    #endif
    

    

}
///检查世界坐标是否位于主灯光的阴影之中(0表示不在阴影中，大于0表示在阴影中,数值代表了阴影强度)
float GetMainLightShadowAtten(float3 positionWS,float3 normalWS)
{
    #if _RECEIVE_SHADOWS_OFF
    return 0;
    #else
    if(_ShadowParams.z == 0)
    {
        return 0;
    }
    int cascadeIndex = GetCascadeIndex(positionWS);

    positionWS = MyApplyShadowBias(positionWS,normalWS,_VMainLightDirection);
    
    float3 shadowMapPos = WorldToShadowMapPos(positionWS,cascadeIndex);
    float shadowStrength = SampleShadowStrength(shadowMapPos);
    
    return shadowStrength * _ShadowParams.z;
    #endif
}
#endif